package com.crazy.cloud.user.domain.repository;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.SqlHelper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.toolkit.ReflectionKit;
import com.crazy.cloud.common.utils.ConvertUtils;
import java.util.Collection;
import java.util.List;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @program: crazy-cloud
 * @description: 基础repository
 * @author: CrazyMan
 * @create: 2018/9/26 上午11:23
 **/
@Slf4j
public abstract class BaseRepository<M extends BaseMapper<T>, T, E> {

    @Autowired
    @Getter
    private M baseMapper;


    public Integer insert(E entity) {
        T entityDO = convertToDO(entity);
        return this.baseMapper.insert(entityDO);
    }

    public Integer updateByEntityId(String entityId, E entity) {
        T entityDO = convertToDO(entity);
        Wrapper<T> doWrapper = new EntityWrapper<T>()
            .eq(getEntityIdColumn(), entityId);
        return this.baseMapper.update(entityDO, doWrapper);
    }


    public E selectByEntityId(String entityId) {
        Wrapper<T> doWrapper = new EntityWrapper<T>()
            .eq(getEntityIdColumn(), entityId)
            .last("LIMIT 1");
        T entityDO = SqlHelper.getObject(this.baseMapper.selectList(doWrapper));
        return convert(entityDO);
    }


    public List<E> selectBatchEntityIds(Collection<String> entityId) {
        Wrapper<T> doWrapper = new EntityWrapper<T>()
            .in(getEntityIdColumn(), entityId);
        List<T> entityDO = this.baseMapper.selectList(doWrapper);
        return convertDOList(entityDO);
    }

    public List<E> selectList(Wrapper wrapper) {
        return convertDOList(this.baseMapper.selectList(wrapper));
    }

    public int count(Wrapper wrapper) {
        return SqlHelper.retCount(this.baseMapper.selectCount(wrapper));
    }

    public int update(E entity, Wrapper wrapper) {
        T t = convertToDO(entity);
        return SqlHelper.retCount(this.baseMapper.update(t, wrapper));
    }

    public Integer deleteByEntityId(String entityId) {
        Wrapper wrapper = new EntityWrapper();
        wrapper.eq(getEntityIdColumn(), entityId);
        return this.baseMapper.delete(wrapper);
    }

    public Integer deleteBatchEntityIds(Collection<String> entityIds) {
        Wrapper wrapper = new EntityWrapper();
        wrapper.in(getEntityIdColumn(), entityIds);
        return this.baseMapper.delete(wrapper);
    }

    public Page<E> selectPage(Page<E> page, Wrapper wrapper) {
        if (page.getSize() > 0) {
            SqlHelper.fillWrapper(page, wrapper);
            page.setRecords(convertDOList(this.baseMapper.selectPage(page, wrapper)));
        } else {
            wrapper.last("LIMIT 1000");
            page.setRecords(convertDOList(this.baseMapper.selectList(wrapper)));
            page.setTotal(page.getRecords().size());
            page.setSize((int) page.getTotal());

        }

        return page;
    }

    protected Class<T> currentDOClass() {
        return ReflectionKit.getSuperClassGenricType(this.getClass(), 1);
    }

    protected Class<E> currentEntityClass() {
        return ReflectionKit.getSuperClassGenricType(this.getClass(), 2);
    }

    protected T convertToDO(E entity) {
        return ConvertUtils.convert(entity, currentDOClass());
    }

    protected List<E> convertDOList(List<T> doList) {
        return ConvertUtils.convert(doList, currentEntityClass());
    }

    protected E convert(T doList) {
        return ConvertUtils.convert(doList, currentEntityClass());
    }

    /**
     * 返回实体类唯一标识
     *
     * @return String
     */
    protected abstract String getEntityIdColumn();

}
